﻿using Coolzon.Common;
using Coolzon.Common.Config;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using RT = Coolzon.Metadata.Runtime;

namespace Coolzon.WebServer.Code.Common
{
    /// <summary>
    /// 启动类
    /// </summary>
    public static class Startup
    {
        private static bool _isStaruping = true;
        /// <summary>
        /// 是否处于启动中
        /// </summary>
        public static bool IsStaruping
        {
            get
            {
                return _isStaruping;
            }
            set
            {
                _isStaruping = value;
            }
        }

        /// <summary>
        /// 是否启动成功
        /// </summary>
        public static bool IsStarupSuccess { get; set; }

        public static void Run()
        {
            IsStarupSuccess = LoadConfig();

            if (IsStarupSuccess)
            {
                Logger.InitByLogDirectory(HttpContext.Current.Server.MapPath("~/logs/"));
                IsStarupSuccess = LoadLibraries();
            }

            if (IsStarupSuccess)
            {
                // 加载方案
                LoadSolutions();

                VerifySolutions();
            }
            IsStaruping = false;
        }

        public static bool LoadConfig()
        {
            try
            {
                Config.Current = JsonConfigUtil.LoadFromString<Config>(File.ReadAllText(HttpContext.Current.Server.MapPath("~/Configs/WebApp.json")));
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public static bool LoadLibraries()
        {
            DirectoryInfo[] libraryDirecties = new DirectoryInfo(Config.Current.LibraryStorageDirectory).GetDirectories();
            foreach (var libraryDirectory in libraryDirecties)
            {
                string libraryJsonFilepath = Path.Combine(libraryDirectory.FullName, "library.json");
                if(File.Exists(libraryJsonFilepath))
                {
                    try
                    {
                        Web.Models.Library library = Coolzon.Common.Config.JsonConfigUtil.LoadFromFile<Web.Models.Library>(libraryJsonFilepath);
                        library.AbsoluteDirectory = string.Format("{0}\\", libraryDirectory.FullName);
                        bool isNeedLoad = false;
                        bool isHasSameName = false;
                        for (int libIndex = 0; libIndex < ServerData.Instance.Libraries.Count; libIndex++)
                        {
                            if(string.Equals(ServerData.Instance.Libraries[libIndex].Name, library.Name, StringComparison.CurrentCultureIgnoreCase))
                            {
                                isHasSameName = true;
                                if (ServerData.Instance.Libraries[libIndex].GetVersion() < library.GetVersion())
                                {
                                    Logger.Info(string.Format("发现library:{0} {1},替换{2} {3}", library.Name, library.Version, ServerData.Instance.Libraries[libIndex].Name, ServerData.Instance.Libraries[libIndex].Version));
                                    ServerData.Instance.Libraries[libIndex] = library;
                                    isNeedLoad = true;
                                    break;
                                }
                                else
                                {
                                    isNeedLoad = false;
                                }
                            }
                        }

                        if(!isHasSameName)
                        {
                            ServerData.Instance.Libraries.Add(library);
                            Logger.Info(string.Format("发现library:{0} {1}", library.Name, library.Version));
                            isNeedLoad = true;
                        }

                        if (!isNeedLoad)
                        {
                            continue;
                        }

                        FileInfo[] files = libraryDirectory.GetFiles();
                        int existDLLFileCount = 0;
                        foreach (var file in files)
                        {
                            if(string.Equals(file.Name, library.File, StringComparison.CurrentCultureIgnoreCase))
                            {
                                existDLLFileCount++;
                            }
                            else
                            {
                                foreach (var dependencyFile in library.Dependencies)
                                {
                                    if (string.Equals(file.Name, dependencyFile.File, StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        existDLLFileCount++;
                                        break;
                                    }
                                }
                            }
                        }

                        if(existDLLFileCount < library.Dependencies.Length + 1)
                        {
                            throw new Exception(string.Format("library:{0}中定义的DLL文件并不是全部存在!", library.Name));
                        }
                    }
                    catch(Exception ex)
                    {
                        Logger.Error(ex.ToString());
                        return false;
                    }
                }
            }
            return true;
        }

        public static void VerifySolutions()
        {
            Logger.InfoToTag("Server", "验证方案文件版本信息...");

            if (ServerData.Instance.SolutionList != null)
            {
                ServerData.Instance.Solutions = new List<RT.SolutionPackage>();

                for (int index = 0; index < ServerData.Instance.SolutionList.Count; index++)
                {
                    // 扫描方案的文件生成最新的方案文件版本信息的记录文件
                    RT.SolutionPackage solution = VerifySolution(ServerData.Instance.SolutionList[index].Name);
                    if(solution!=null)
                    {
                        ServerData.Instance.Solutions.Add(solution);
                    }
                }
            }

            Logger.InfoToTag("Server", "验证方案文件版本信息完毕");
        }

        public static void LoadSolutions()
        {
            Logger.InfoToTag("Server", "加载方案列表...");

            // 读取方案到内存中
            ServerData.Instance.SolutionList = RT.SolutionXmlProxy.LoadSolutionList(Config.GetSolutionSummaryFile());

            if (ServerData.Instance.SolutionList != null)
            {
                foreach (var solutionRef in ServerData.Instance.SolutionList)
                {
                    Logger.InfoToTag("Server", string.Format("方案:{0},Caption:{1},Version:{2},RuntimeVersion:{3}", solutionRef.Name, solutionRef.Caption, solutionRef.Version, solutionRef.RuntimeVersion));
                }
            }
            else
            {
                Logger.InfoToTag("Server", "加载方案列表完毕,没有发现任何方案");
            }
        }
        
        /// <summary>
        /// 扫描验证方案文件，生成版本记录，同时将方案的版本记录加载到内存中
        /// </summary>
        /// <param name="solutionName">方案名称</param>
        private static RT.SolutionPackage VerifySolution(string solutionName)
        {
            string solutionDir = Config.GetSolutionDirectory(solutionName);
            return RT.FileMD5Helper.GetSolutionPackage(solutionDir);
        }
    }
}